open Ast
open Json
open Functions

let rec node_to_json = function
  | TextNode xx -> JsonObject (None, [("xtype", JsonString "box"); ("html", JsonString (join "" xx))])
  | ElementNode {tagname=x; attributes=attrs; children=children; comment=comment} as node -> 
  		match x with
  		  | "border" | "form" | "vbox" | "hbox" | "absolute" | "accordion" | "anchor" | "table"
  		  		-> gen comment (("layout", JsonString x) :: attrs_to_json attrs) children
  		  
  		  | "east" | "west" | "north" | "south" | "center"
  		  		-> gen comment (("region", JsonString x) :: attrs_to_json attrs) children
  		  | "fill"       -> JsonString "->"
(*  		  | "spacer"     -> JsonString " "  *)
  		  | "separator"  -> JsonString "-"
  		  | "button"     -> gen comment ([
  		  			                ("xtype", JsonString x);
                                    ("text", JsonString (node_list_to_plain_string children));
                                 ] @ (attrs_to_json attrs)) []
  		  | "tab"        -> gen comment (attrs_to_json attrs) children

			| "arraystore" | "barchart" | "box" | "button" | "buttongroup" | "cartesianchart" 
			| "chart" | "checkbox" | "checkboxgroup" | "colormenu" | "colorpalette" | "columnchart" 
			| "combo" | "component" | "compositefield" | "container" | "cycle" | "dataview" 
			| "datefield" | "datemenu" | "datepicker" | "directstore" | "displayfield" | "editor" 
			| "editorgrid" | "field" | "fieldset" | "flash" | "form" | "grid" 
			| "groupingstore" | "hidden" | "htmleditor" | "jsonstore" | "label" | "linechart" 
			| "listview" | "menu" | "menubaseitem" | "menucheckitem" | "menuitem" | "menuseparator" 
			| "menutextitem" | "multislider" | "numberfield" | "paging" | "panel" | "piechart" 
			| "progress" | "propertygrid" | "radio" | "radiogroup" | "simplestore" | "slider" 
			| "spacer" | "splitbutton" | "store" | "tabpanel" | "tbbutton" | "tbfill" 
			| "tbitem" | "tbseparator" | "tbspacer" | "tbsplit" | "tbtext" | "textarea" 
			| "textfield" | "timefield" | "toolbar" | "treepanel" | "trigger" | "viewport" 
			| "window" | "xmlstore"
				-> gen comment (("xtype", JsonString x) :: attrs_to_json attrs) children
  		  
  		  | _ -> JsonObject (comment, [("xtype", JsonString "box"); ("html", JsonString (node_to_plain_string node))])
  		

and gen comment props = function
  | [] -> JsonObject (comment, props)
  | xx -> JsonObject (comment, props @ [("items", JsonArray (map node_to_json xx))])

and attr_to_json = function 
  | (k, None) -> (attr_name k, JsonTrue)
  | ("onclick", Some v) -> ("listeners", JsonObject (None, [("click", JsonFunction (Str.global_replace (Str.regexp "\\\\'") "'" v))]))
  | (k, Some v) -> (attr_name k, atom_to_json v)

and attr_name = function
  | "autoheight" -> "autoHeight"
  | "dataindex" -> "dataIndex"
  | "activetab" -> "activeTab"
  | "bodyborder" -> "bodyBorder"
  | x -> x

and attrs_to_json xx = map attr_to_json xx

and atom_to_json x = if is_number x then JsonNumber x else JsonString x

let program_to_json = function
  | [] -> JsonNull
  | hd :: [] -> node_to_json hd
  | xx -> JsonArray (map node_to_json xx)

